package com.yicheng.statistics.actor.analysis

import akka.actor.Actor
import akka.actor.ActorLogging
import akka.actor.ActorRef
import akka.actor.Props
import com.yicheng.statistics.common.HTADB
import com.yicheng.statistics.service.HTAService
import com.yicheng.statistics.repo.cassandra.DataInfoDB
import com.yicheng.statistics.common.TimeUtils
import scala.util.Failure
import scala.util.Success
import java.util.Date
import com.yicheng.statistics.common.RTAModel.VehicleTiredSetting
import org.joda.time.DateTime
import com.yicheng.statistics.repo.RTAModel.VehicleTired
import com.yicheng.statistics.repo.model.Data.DataInfo
import com.carcloud.gateway.bean.data.DataVehPos
import com.carcloud.gateway.bean.data.DataVehOverall
import com.yicheng.statistics.actor.AnalysisParser
import com.yicheng.statistics.actor.SaveHtaData
import akka.actor.SupervisorStrategy.Stop

class TriedDriveManyAlarm extends Actor with ActorLogging with AnalysisParser{
  val saveHtaDataActor:ActorRef = context.child("saveHtaData").
    getOrElse(context.actorOf(Props[SaveHtaData], "saveHtaData"))
  
  import scala.concurrent.ExecutionContext.Implicits.global
  def receive: Receive = {
    case (deviceId:String,deviceType:Int, analyseGroupId:Long) =>
      log.info("疲劳驾驶 deviceId "+deviceId)
      val tiredTimeState = TiredTimeState(false, true, None, None,Some(0), Some(0),Some(0), None,None, None,None, 0, false, None)
      val mileageState = MileageState(None, None, Some(0), None, None, None, None)
      val tiredState = TiredState(tiredTimeState, mileageState, deviceId, deviceType)
      
      HTADB.getVehicleTiredSettings(analyseGroupId).map(s => 
        if( !s.headOption.isEmpty){
          parseOneDayDataInfo(deviceType, deviceId, tiredState, s.headOption.get, Parser _)
        }
        
      )
    case Stop =>
      //context.parent ! Stop
      log.info("tireddrive stop")
      context.actorSelection("/user/daemon") ! TiredStop
    case _ => log.info("TriedDrive")
  }
  
  type S = VehicleTiredSetting
  
  def Parser(state:TiredState, setting:VehicleTiredSetting , dataInfos : Seq[DataInfo], isEnd:Boolean): TiredState = {
    var tiredTimeState:TiredTimeState = state.tiredTimeState//
    var mileageState : MileageState = state.mileageState//
    
    val deviceId = state.deviceId
    val deviceType = state.deviceType
    val dayTimeWarnning =  setting.timeThreshold - setting.earlyWarningThreshold//提前预警时间
    val dayWarnnigStartTime = TimeUtils.time2DateTime(setting.startTime, TimeUtils.getPreDateTime()).toDate().getTime()
    val dayWarnnigEndTime = TimeUtils.time2DateTime(setting.endTime, TimeUtils.getPreDateTime()).toDate().getTime()
    var timeThreshold = setting.timeThreshold
    val resttime = setting.effectiveRestTime//
    log.info(dataInfos.toString())
    
    dataInfos foreach {
      di =>
        val posData: DataVehPos = di.data_vehicle.posData.get
        val overAllData: DataVehOverall = di.data_vehicle.overallData.get
        
        //夜间间行车
        if(TimeUtils.inTimeRang(setting.nightDriveBeginTime.get, setting.nightDriveendTime.get, di.data_time)){
          timeThreshold = setting.nightTimeThreshold.get
        }
        //日间行车
        if( TimeUtils.inTimeRang(setting.startTime, setting.endTime, di.data_time)){
          timeThreshold = setting.timeThreshold
        }
        
        if(tiredTimeState.startTime.isEmpty){
          tiredTimeState = tiredTimeState.copy(
              startTime = Some(di.data_time), 
              startLat = Some(posData.getLatitude), 
              startLon = Some(posData.getLongitude), 
              lastData = Some(di))
        }else{
          
          //如果休息够了时间 重新计算报警 发送报警统计
          if(TimeUtils.secondsBetweenTime(tiredTimeState.lastData.get.data_time, di.data_time) > setting.effectiveRestTime){
            
            //
            if( tiredTimeState.start){
              val alarmtime = TimeUtils.secondsBetweenTime(tiredTimeState.startTime.get, tiredTimeState.lastData.get.data_time)
              val endMileage = tiredTimeState.lastData.get.data_vehicle.overallData.get.currentMileage
              val alarmMilegae = endMileage - mileageState.startMileage.get
              val ct = VehicleTired(
                  deviceType,
                  deviceId,
                  tiredTimeState.startTime,
                  tiredTimeState.endTime,
                  Some(setting.minDistance),
                  Some(timeThreshold),
                  Some(alarmtime.toInt),
                  tiredTimeState.startLon,
                  tiredTimeState.startLat,
                  Some(tiredTimeState.lastData.get.data_vehicle.posData.get.getLongitude), 
                  Some(tiredTimeState.lastData.get.data_vehicle.posData.get.getLatitude),
                  mileageState.startMileage,
                  Some(endMileage),
                  totalmileage = Some(alarmMilegae),
                  analysegroupsid = Some(setting.analyseGroupsID.toInt),
                  analyseconditions = Some(""),
                  createdatetime = DateTime.now().toDate())
                  
              saveHtaDataActor ! ct
              
              mileageState = mileageState.copy(
                startMileage = Some(overAllData.currentMileage),
                alarmTotalMileage = Some(0))
              tiredTimeState = TiredTimeState(false, true, None, None,Some(0), Some(0),Some(0), None,None, None,None, 0, false, Some(di))
              
            }
          }else {
            
            val totalTime = TimeUtils.secondsBetweenTime(tiredTimeState.startTime.get, di.data_time)
            
            //当达到初始报警条件(没有报警并且持续时间已经大于阀值)
            if( tiredTimeState.totalTime.get > timeThreshold 
                && (mileageState.driveMileage.get > setting.minDistance)
                && !tiredTimeState.start){
              
              tiredTimeState = tiredTimeState.copy(
                start = true,
                startTime = Some(di.data_time), 
                startLat = Some(posData.getLatitude), 
                startLon = Some(posData.getLongitude),
                lastData = Some(di))
              
              mileageState = mileageState.copy(
                startMileage = Some(overAllData.currentMileage),
                alarmTotalMileage = Some(0))
            }
          }
          
        }
    }
    
    if(isEnd && tiredTimeState.start){
      val alarmtime = TimeUtils.secondsBetweenTime(tiredTimeState.startTime.get, tiredTimeState.lastData.get.data_time)
      val endMileage = tiredTimeState.lastData.get.data_vehicle.overallData.get.currentMileage
      val alarmMilegae = endMileage - mileageState.startMileage.get
      val ct = VehicleTired(
          deviceType,
          deviceId,
          tiredTimeState.startTime,
          tiredTimeState.endTime,
          Some(setting.minDistance),
          Some(timeThreshold),
          Some(alarmtime.toInt),
          tiredTimeState.startLon,
          tiredTimeState.startLat,
          Some(tiredTimeState.lastData.get.data_vehicle.posData.get.getLongitude), 
          Some(tiredTimeState.lastData.get.data_vehicle.posData.get.getLatitude),
          mileageState.startMileage,
          Some(endMileage),
          totalmileage = Some(alarmMilegae),
          analysegroupsid = Some(setting.analyseGroupsID.toInt),
          analyseconditions = Some(""),
          createdatetime = DateTime.now().toDate())
          
      saveHtaDataActor ! ct
              
    }
    
    TiredState(tiredTimeState, mileageState, deviceId, deviceType)
  }
}

case class TiredStop()